package tools

import (
	"encoding/json"
	"fmt"
	"strconv"

	"mysql-mcp-server-go/internal/database"
	"mysql-mcp-server-go/pkg/logger"
)

// Tool MCP工具定义
type Tool struct {
	Name        string          `json:"name"`
	Description string          `json:"description"`
	InputSchema ToolInputSchema `json:"inputSchema"`
}

// ToolInputSchema 工具输入模式
type ToolInputSchema struct {
	Type       string                 `json:"type"`
	Properties map[string]interface{} `json:"properties"`
	Required   []string               `json:"required"`
}

// ToolResult 工具执行结果
type ToolResult struct {
	Content []ToolContent `json:"content"`
	IsError bool          `json:"isError,omitempty"`
}

// ToolContent 工具内容
type ToolContent struct {
	Type string `json:"type"`
	Text string `json:"text"`
}

// ToolManagerInterface 工具管理器接口
type ToolManagerInterface interface {
	GetAvailableTools() []Tool
	ExecuteTool(toolName string, arguments map[string]interface{}) (*ToolResult, error)
}

// ToolManager 工具管理器
type ToolManager struct {
	db     database.DatabaseInterface
	logger logger.Logger
}

// New 创建新的工具管理器
func New(db database.DatabaseInterface) *ToolManager {
	return &ToolManager{
		db:     db,
		logger: logger.New(false), // 暂时使用false，后续可以从配置中获取
	}
}

// GetAvailableTools 获取所有可用的工具定义
func (tm *ToolManager) GetAvailableTools() []Tool {
	return []Tool{
		{
			Name:        "list-tables",
			Description: "列出数据库中的所有表",
			InputSchema: ToolInputSchema{
				Type:       "object",
				Properties: map[string]interface{}{},
				Required:   []string{},
			},
		},
		{
			Name:        "describe-table",
			Description: "获取指定表的结构信息",
			InputSchema: ToolInputSchema{
				Type: "object",
				Properties: map[string]interface{}{
					"table_name": map[string]interface{}{
						"type":        "string",
						"description": "要查看结构的表名",
					},
				},
				Required: []string{"table_name"},
			},
		},
		{
			Name:        "execute-query",
			Description: "执行SQL查询并返回结果",
			InputSchema: ToolInputSchema{
				Type: "object",
				Properties: map[string]interface{}{
					"query": map[string]interface{}{
						"type":        "string",
						"description": "要执行的SQL查询语句",
					},
					"limit": map[string]interface{}{
						"type":        "integer",
						"description": "结果限制数量（可选，默认1000）",
						"default":     1000,
						"minimum":     1,
						"maximum":     10000,
					},
				},
				Required: []string{"query"},
			},
		},
	}
}

// ExecuteTool 执行指定的工具
func (tm *ToolManager) ExecuteTool(toolName string, arguments map[string]interface{}) (*ToolResult, error) {
	tm.logger.WithField("tool_name", toolName).Debug("开始执行工具")
	
	var result *ToolResult
	var err error
	
	switch toolName {
	case "list-tables":
		result, err = tm.executeListTables()
	case "describe-table":
		result, err = tm.executeDescribeTable(arguments)
	case "execute-query":
		result, err = tm.executeQuery(arguments)
	default:
		tm.logger.WithField("tool_name", toolName).Warn("收到未知工具请求")
		return &ToolResult{
			Content: []ToolContent{
				{
					Type: "text",
					Text: fmt.Sprintf("未知的工具: %s", toolName),
				},
			},
			IsError: true,
		}, nil
	}
	
	if err != nil {
		tm.logger.WithError(err).WithField("tool_name", toolName).Error("工具执行失败")
		return result, err
	}
	
	tm.logger.WithField("tool_name", toolName).Debug("工具执行成功")
	return result, nil
}

// executeListTables 执行列表表工具
func (tm *ToolManager) executeListTables() (*ToolResult, error) {
	tm.logger.Debug("开始获取数据库表列表")
	
	tables, err := tm.db.ListTables()
	if err != nil {
		tm.logger.WithError(err).Error("获取表列表失败")
		return &ToolResult{
			IsError: true,
			Content: []ToolContent{
				{
					Type: "text",
					Text: fmt.Sprintf("获取表列表失败: %v", err),
				},
			},
		}, nil
	}

	tm.logger.WithField("table_count", len(tables)).Info("成功获取表列表")

	// 格式化表列表
	var content string
	if len(tables) == 0 {
		content = "数据库中没有找到任何表"
	} else {
		content = fmt.Sprintf("数据库中共有 %d 个表:\n", len(tables))
		for i, table := range tables {
			content += fmt.Sprintf("%d. %s\n", i+1, table)
		}
	}

	return &ToolResult{
		IsError: false,
		Content: []ToolContent{
			{
				Type: "text",
				Text: content,
			},
		},
	}, nil
}

// executeDescribeTable 执行描述表工具
func (tm *ToolManager) executeDescribeTable(arguments map[string]interface{}) (*ToolResult, error) {
	// 获取表名参数
	tableName, ok := arguments["table_name"].(string)
	if !ok {
		tm.logger.Error("缺少必需的参数: table_name")
		return &ToolResult{
			IsError: true,
			Content: []ToolContent{
				{
					Type: "text",
					Text: "缺少必需的参数: table_name",
				},
			},
		}, nil
	}

	tm.logger.WithField("table_name", tableName).Debug("开始获取表结构信息")

	// 获取表结构
	columns, err := tm.db.DescribeTable(tableName)
	if err != nil {
		tm.logger.WithError(err).WithField("table_name", tableName).Error("获取表结构失败")
		return &ToolResult{
			IsError: true,
			Content: []ToolContent{
				{
					Type: "text",
					Text: fmt.Sprintf("获取表结构失败: %v", err),
				},
			},
		}, nil
	}

	tm.logger.WithFields(map[string]interface{}{
		"table_name":   tableName,
		"column_count": len(columns),
	}).Info("成功获取表结构信息")

	// 格式化表结构信息
	content := fmt.Sprintf("表 '%s' 的结构信息:\n\n", tableName)
	content += "字段名\t\t类型\t\t\t允许NULL\t主键\t默认值\t\t额外信息\n"
	content += "------------------------------------------------------------------------\n"

	for _, col := range columns {
		content += fmt.Sprintf("%-15s\t%-20s\t%-8s\t%-4s\t%-15s\t%s\n",
			col.Field, col.Type, col.Null, col.Key, col.Default, col.Extra)
	}

	// 同时返回JSON格式的结构化数据
	jsonData, _ := json.MarshalIndent(columns, "", "  ")

	return &ToolResult{
		IsError: false,
		Content: []ToolContent{
			{
				Type: "text",
				Text: content,
			},
			{
				Type: "text",
				Text: fmt.Sprintf("\nJSON格式:\n%s", string(jsonData)),
			},
		},
	}, nil
}

// executeQuery 执行查询工具
func (tm *ToolManager) executeQuery(arguments map[string]interface{}) (*ToolResult, error) {
	// 获取查询参数
	query, ok := arguments["query"].(string)
	if !ok {
		tm.logger.Error("缺少必需的参数: query")
		return &ToolResult{
			IsError: true,
			Content: []ToolContent{
				{
					Type: "text",
					Text: "缺少必需的参数: query",
				},
			},
		}, nil
	}

	// 获取限制参数（可选）
	limit := 1000 // 默认值
	if limitValue, exists := arguments["limit"]; exists {
		switch v := limitValue.(type) {
		case float64:
			limit = int(v)
		case int:
			limit = v
		case string:
			if parsedLimit, err := strconv.Atoi(v); err == nil {
				limit = parsedLimit
			}
		}
	}

	// 验证限制范围
	if limit < 1 {
		limit = 1
	} else if limit > 10000 {
		limit = 10000
	}

	tm.logger.WithFields(map[string]interface{}{
		"query": query,
		"limit": limit,
	}).Debug("开始执行SQL查询")

	// 执行查询
	result, err := tm.db.ExecuteQuery(query, limit)
	if err != nil {
		tm.logger.WithError(err).WithFields(map[string]interface{}{
			"query": query,
			"limit": limit,
		}).Error("SQL查询执行失败")
		return &ToolResult{
			IsError: true,
			Content: []ToolContent{
				{
					Type: "text",
					Text: fmt.Sprintf("查询执行失败: %v", err),
				},
			},
		}, nil
	}

	tm.logger.WithFields(map[string]interface{}{
		"query": query,
		"limit": limit,
	}).Info("SQL查询执行成功")

	return &ToolResult{
		IsError: false,
		Content: []ToolContent{
			{
				Type: "text",
				Text: result,
			},
		},
	}, nil
}